close all
clear all
clc

%**************************************************************************

% Parameters to be tuned

% #hidden dimensions
D = 10;

% Variance of rating entries
sigma_r = 0.2;

% Learning rate
eta = 0.001;

% Maximum number of iterations allowed
maxIters = 100;

% Minimum number of iterations allowed
minIters = 10;

% The minimum percentage of error decrease to be considered as "updating"
thresPercent = 0.001;

%**************************************************************************

% Initialization

% input = load('mlimdb_rating_genre.mat');
% R = input.org_rating;
% G = input.genre;
input = load('flixSub_bigNet_train.mat');
R = input.trainSet;
mask = ones(size(R)) & R;

% Convert the rating values to [0 1]
R = R/5.0;

N = size(R, 1);     % #users
M = size(R, 2);     % #movies

%**************************************************************************

% S = load('flixSub_links.mat');
% G = S.Graph;
% graphKernel(Graph);

% Calculate the user kernel matrix
% calcUserKernel(R);

% Calculate the movie kernel matrix
% calcMovieKernel(R);

% Load the user kernel matrix
% S = load('flixSub_bigNet_user_diff_kernel.mat');
% K_u = S.K;
% % 
% S = load('flixSub_bigNet_user_diff_kernel_inv.mat');
% K_u_inv = S.K_inv;

K_u = 0.2 * eye(N,N);
K_u_inv = inv(K_u);

% Load the movie kernel matrix
% S = load('u1_movie_exp_kernel.mat');
% K_v = S.K_v;

% S = load('u1_movie_exp_kernel_inv.mat');
% K_v_inv = S.K_v_inv;
% 
K_v = 0.2 * eye(M,M);
K_v_inv = inv(K_v);

[U, V] = kpmf_grad_descent(R, mask, D, K_u_inv, K_v_inv, sigma_r, eta, maxIters, minIters, thresPercent);

%**************************************************************************
S = load('flixSub_bigNet_test.mat');
R2 = S.testSet;
R2 = R2/5.0;
mask2 = ones(size(R2)) & R2;

n = sum(mask2(:));
tmpMat = mask2.*((R2 - U*V').^2);
RMSE = sqrt(sum(tmpMat(:))/n)
